package cn.ffcs.tmp.web;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.Map.Entry;
import java.io.BufferedInputStream;
import java.io.FileInputStream;

import java.io.*;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.Item;
import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.RichTextItem;
import lotus.domino.Session;
import lotus.domino.View;

import org.apache.log4j.Logger;
import org.apache.struts.upload.FormFile;
import org.apache.struts2.ServletActionContext;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import com.opensymphony.xwork2.ActionContext;

import cn.ffcs.base.model.BaseEntity;
import cn.ffcs.base.web.BaseAction;
import cn.ffcs.base.web.PageControl;
import cn.ffcs.common.model.Attach;
import cn.ffcs.common.service.AttachService;
import cn.ffcs.product.model.ProductReference;
import cn.ffcs.product.service.ProductReferenceService;
import cn.ffcs.security.model.User;
import cn.ffcs.share.model.ShareReference;
import cn.ffcs.share.service.ShareReferenceService;
import cn.ffcs.system.dict.model.Dict;
import cn.ffcs.system.dict.model.DictType;
import cn.ffcs.system.dict.service.DictService;
import cn.ffcs.system.dict.service.DictTypeService;
import cn.ffcs.util.context.ApplicationContextUtil;
import cn.ffcs.util.properties.PropertiesUtil;
import cn.ffcs.tmp.model.Annex;
import cn.ffcs.tmp.service.AnnexService;
import cn.ffcs.tmp.service.IAnnexService;

/**
 * 业务action层<br/> <table>
 * <tr>
 * <td>负责人/principal:</td>
 * <td colspan="2">pany</td>
 * <tr>
 * <td>修改记录/revision:</td>
 * <td colspan="2"></td>
 * </tr>
 * <tr>
 * <td>日期:</td>
 * <td>修改人:</td>
 * <td>修改说明:</td>
 * </tr>
 * <tr>
 * <td></td>
 * <td></td>
 * <td></td>
 * </tr>
 * </table>
 * @author pany
 * @version $Id$
 */
public class AnnexAction<A extends Annex> extends BaseAction<A>
{
    /** 日志 * */
    Logger log = Logger.getLogger(this.getClass());

    private static final int BUFFER_SIZE = 16 * 1024;
    /** 业务POJO * */
    private A annex;
    /** 上载文件* */
    public File uploadFile;
    /** 内容 * */
    private String contentType;
    /** 文件名称 * */
    private String fileName;
    /** 输入流 * */
    private ByteArrayInputStream inputStream;
    /** 上传文件 * */
    public File uFile;
    /** 图片显示宽度 * */
    public int imgWidth = 1;
    /** 图片显示高度 * */
    public int imgHeight = 1;
    /** 数据字典服务 * */
    private DictService dictService;
    /** 附件服务 * */
    private AttachService attachService;
    /** 数据字典类型服务 * */
    private DictTypeService dictTypeService;
    /** 当前资料细类类型 * */
    private String refType;
    /** 资料类型数据 * */
    private List<Dict> lRefType;
    /** 密級类型数据 * */
    private List<Dict> lSecretType;
    /** 同步资料服务 * */
    private AnnexService annexService;
    /** 同步资料数据 * */
    private List<Annex> annexList;
    /** 共享资料数据 * */
    private ShareReference shareReference;
    /** 共享资料服务 * */
    private ShareReferenceService shareReferenceService;
    /** 产品资料 * */
    private ProductReference productReference;
    /** 产品资料服务 * */
    private ProductReferenceService productReferenceService;

    private final String ior = "IOR:010000002900000049444c3a6c6f7475732f646f6d696e6f2f636f7262612f494f626a6563745365727665723a312e3000000000010000000000000078000000010101001300000068647a782e666a74656c65636f6d2e636f6d0000f4ea0000310000000438353235363531612d656336382d313036632d656565302d303037653264323233336235004c6f7475734e4f490100010000000100000001000000140000000100000001000105000000000001010000000000";

    private String content;
    
    /**
     * 根据关键值获取实体数据
     * @return
     */
    public String findById()
    {
        String[] ids = getContextObjects("ids");
        if (ids == null || ids.length == 0)
        {
            super.findByPage();
            return "back";
        }
        Annex a;
        annexList = new ArrayList();
        content="";
        for (String id : ids)
        {
            a = (Annex) baseService.findById(new Integer(id));
            annexList.add(a);
            content+=a.getFullName()+"\r\n";
        }
        if(shareReference==null){
            shareReference=new ShareReference();
        }
        shareReference.setContent(content);
        initShare();
        return SUCCESS;
    }

    /**
     * 根据关键值获取实体数据
     * @return
     */
    public String toAnnexArchiveProc()
    {
        String[] ids = getContextObjects("ids");
        if (ids == null || ids.length == 0)
        {
            super.findByPage();
            return "back";
        }
        Annex a;
        annexList = new ArrayList();
        content="";
        for (String id : ids)
        {
            a = (Annex) baseService.findById(new Integer(id));
            annexList.add(a);
            content+=a.getFullName()+"\r\n";
        }
        
        init();
        // /发布人默认为当前操作人员
        productReference = new ProductReference();
        if (productReference != null && !"".equals(productReference))
        {
            Dict dict = new Dict();
            // if (referenceTypeId != null)
            // dict.setId(new Integer(referenceTypeId));
            productReference.setReferenceType(dict);
        }
        User currUser = ApplicationContextUtil.getUserContextObject()
                .getCurrUser();
        if (currUser != null)
        {
            productReference.setCreator(currUser.getUserID());
        }
        productReference.setContent(content);
        return SUCCESS;
    }

    /**
     * 初始化业务数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public String init()
    {
        // 根据实体名称获取字典类型
        String dtKey = new ProductReference().getClass().getSimpleName();
        Criterion condDt = Restrictions.eq("keyValue", dtKey.toUpperCase());
        List<DictType> ldt = this.dictTypeService.findBy(condDt);
        if (ldt != null && ldt.size() > 0)
        {
            DictType dictType = (DictType) ldt.get(0);
            Criterion cond = Restrictions.eq("dictType.id", dictType.getId());
            lRefType = dictService.findBy(cond);
        }
        else
        {
            lRefType = new ArrayList<Dict>();
        }
        return SUCCESS;
    }

    /**
     * 
     * 组合查询条件
     * @return
     */
    public Criterion combineCond()
    {
        HashMap<String, Object> conds = super.getConds();
        if (conds == null)
        {
            conds = new HashMap<String, Object>();
        }
        User currUser = ApplicationContextUtil.getUserContextObject()
            .getCurrUser();
        if (currUser != null&&currUser.getPerson()!=null&&!"".equals(currUser.getPerson().getName()))
        {
            conds.put("creator", currUser.getPerson().getName());
        }
        conds.put("isPublish", 0);
        super.setConds(conds);
        return super.combineCond();
    }

    /**
     * 
     * 保存操作
     * @return
     */
    public String saveOrUpdate()
    {
        String[] ids = getContextObjects("ids");
        if (ids != null && ids.length > 0)
        {
            if (productReference != null)
            {
                // 保存产品资料数据
                productReferenceService.saveOrUpdate(productReference);
                A a;
                annexList = new ArrayList();
                for (String id : ids)
                {
                    a = baseService.findById(new Integer(id));
                    fillObject(a, productReference);
                    a.setIsPublish(1);
                    baseService.update(a);
                }
            }
            else
            {
                // 保存产品资料数据
                shareReferenceService.saveOrUpdate(shareReference);
                A a;
                annexList = new ArrayList();
                for (String id : ids)
                {
                    a = baseService.findById(new Integer(id));
                    fillObject(a, shareReference);
                    a.setIsPublish(1);
                    baseService.update(a);
                }
            }
        }

        findByPage();
        return SUCCESS;
    }

    /**
     * 获取分页数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public String findByPage()
    {
//        linkDomino();
        // 如果第一次装置，默认参数
        if (pageControl == null)
        {
            pageControl = new PageControl();
        }
        pageControl = baseService.findByPage(combineCond(), pageControl
                .getPageNo(), pageControl.getPageSize());
        return SUCCESS;
    }

    /**
     * 连接domino服务器，把附件同步到数据库中
     * TODO 请输入方法说明
     */
    public String linkDomino(){
        try{
            Session session = NotesFactory.createSessionWithIOR(ior);
            // //*创建新会话对象
            // 获取数据库及日志参数
            System.out.println("link");
            Database oadb = session.getDatabase(null, "dx_yunyzxjk.nsf");
            View view = oadb.getView("Yunyzxjk");
            Document doc = view.getFirstDocument();
            System.out.println("start");
            while (doc != null)
            {
                annex=(A)new Annex();
                annex.setFileType("FILE");
                annex.setPrefix("file");
                annex.setName(doc.getItemValueString("Fujm"));
                annex.setRefEntity(annex.getClass().getName());
                annex.setRefEntityID("1");
                annex.setIsPublish(0);

                RichTextItem aa=(RichTextItem)doc.getFirstItem("Body");
                Vector objs=aa.getEmbeddedObjects();
                EmbeddedObject eo;
                
                for (int i = 0; i < objs.size(); i++){
                    eo=(EmbeddedObject)objs.get(i);
                    InputStream input =eo.getInputStream();
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    
                    int len=64*1024;
                    int count=-1;
                    byte[] buffer = new byte[len];
                    while((count=input.read(buffer,0,len))>-1){
                        os.write(buffer,0,count);
                    }
                    byte a[] = os.toByteArray();
                    annex.setId(null);
                    annex.setContent(a);
                    annex.setFullName(doc.getItemValueString("Biaot")+eo.getName());
                    baseService.saveOrUpdate(annex);
                    
                    input.close();
                    os.flush();
                    os.close();
                }
                
                doc = view.getNextDocument(doc);
            }
            view.recycle();
            oadb.recycle();
            session.recycle();
            System.out.println("end");
        }
        catch (NotesException n)
        {
            n.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        this.findByPage();
        return SUCCESS;
    }
    
    public Attach fillObject(Annex a, BaseEntity entity)
    {
        Attach attach = new Attach();
        attach.setName(a.getName());
        attach.setFullName(a.getFullName());
        attach.setCreator(a.getCreator());
        attach.setFileType(a.getFileType());
        attach.setPrefix(a.getPrefix());
        attach.setContent(a.getContent());
        attach.setRefEntity(entity.getClass().getName());
        attach.setRefEntityID(entity.getId() + "");
        attach.setIsPublish(a.getIsPublish());
        attachService.saveOrUpdate(attach);
        return attach;
    }

    /**
     * 
     * 初始化业务数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public String initShare()
    {
        this.initDict("SECRET");
        if (refType == null || "".equals(refType)) refType = "_SHARE";
        this.initDict(refType);
        return SUCCESS;
    }

    /**
     * 
     * 初始化字典数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public void initDict(String sDictType)
    {
        if (sDictType == null || sDictType.equals(""))
        {
            return;
        }
        Criterion cond = Restrictions.like("keyValue", "%" + sDictType + "%");
        List dictType = dictTypeService.findBy(cond);
        if (dictType != null && dictType.size() > 0)
        {
            for (int i = 0; i < dictType.size(); i++)
            {
                Criterion dtcond = Restrictions.eq("dictType.id",
                        ((DictType) dictType.get(i)).getId());
                if (sDictType.equals("SECRET"))
                {
                    lSecretType = dictService.findBy(dtcond);
                    break;
                }
                else
                {
                    if (lRefType == null)
                    {
                        lRefType = dictService.findBy(dtcond);
                    }
                    else
                    {
                        lRefType.addAll(dictService.findBy(dtcond));
                    }
                }
            }
        }
        else
        {
            if (sDictType.equals("SECRET"))
            {
                lSecretType = new ArrayList();
            }
            else if (sDictType.equals("SHARE_TYPE"))
                lRefType = new ArrayList();
        }
        return;
    }

    /**
     * 上载文件
     * @return
     */
    public String uploadFile()
    {
        return SUCCESS;
    }

    /**
     * 保存上载文件
     * @return
     * @throws Exception
     */
    public String saveUploadFile() throws Exception
    {
        byte[] result = new byte[BUFFER_SIZE];
        result = FileUtils.readFileToByteArray(uploadFile);
        FileUtils.forceDelete(uploadFile);
        String fullName = fileName;
        String name = fullName.substring(0, fullName.indexOf("."));
        String prefix = fullName.substring(fullName.indexOf(".") + 1, fullName
                .length());
        annex.setContent(result);
        annex.setFileType("FILE");
        annex.setFullName(fullName);
        annex.setName(name);
        annex.setPrefix(prefix);
        annex.setRefEntity(annex.getClass().getName());
        annex.setRefEntityID("1");
        annex.setIsPublish(1);
        baseService.saveOrUpdate(annex);
        return SUCCESS;
    }

    /**
     * 文件下载
     * @return
     * @throws Exception
     */
    public String showFile() throws Exception
    {
        findById();
        String fileName = annex.getFullName();
        ActionContext ctx = ActionContext.getContext();
        HttpServletRequest request = (HttpServletRequest) ctx
                .get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ctx
                .get(ServletActionContext.HTTP_RESPONSE);
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition", "annexment;" + " filename="
                + new String(fileName.getBytes("gb2312"), "iso8859-1"));
        write(response.getOutputStream(), annex.getContent());
        return null;
    }

    /**
     * ftp文件下载
     * @return
     * @throws Exception
     */
    public String showFtpFile() throws Exception
    {
        findById();

        String fileName = annex.getFullName();

        ActionContext ctx = ActionContext.getContext();
        HttpServletRequest request = (HttpServletRequest) ctx
                .get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ctx
                .get(ServletActionContext.HTTP_RESPONSE);
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition", "annexment;" + " filename="
                + new String(fileName.getBytes("gb2312"), "iso8859-1"));
        try
        {
            byte[] buffer = new byte[4096]; // 缓冲区

            BufferedOutputStream output = null;
            BufferedInputStream input = null;
            String webUrl = ServletActionContext.getServletContext()
                    .getRealPath("/");
            String filePath = PropertiesUtil.readValue("/poc-ftp.properties",
                    "ftp.path");
            java.io.File f = new java.io.File(webUrl + filePath + "/"
                    + annex.getFullName());
            try
            {
                output = new BufferedOutputStream(response.getOutputStream());
                input = new BufferedInputStream(new FileInputStream(f));
                int n = (-1);
                while ((n = input.read(buffer, 0, 4096)) > -1)
                {
                    output.write(buffer, 0, n);
                }
                response.flushBuffer();
            }
            catch (Exception e)
            {
            } // 用户可能取消了下载
            finally
            {
                if (input != null) input.close();
                if (output != null) output.close();
            }
        }
        catch (Exception e)
        {
            // 如果下载失败了就告诉用户此文件不存在
            e.printStackTrace();
            response.sendError(404);
        }
        return null;
    }

    /**
     * 文件下载
     * @return
     * @throws Exception
     */
    public String showImgFile() throws Exception
    {
        findById();
        String fileName = annex.getFullName();
        ActionContext ctx = ActionContext.getContext();
        HttpServletRequest request = (HttpServletRequest) ctx
                .get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ctx
                .get(ServletActionContext.HTTP_RESPONSE);
        // response.setContentType("application/x-msdownload");
        // response.setHeader("Content-Disposition", "annexment;" + "
        // filename="
        // + new String(fileName.getBytes(), "ISO-8859-1"));
        write(response.getOutputStream(), annex.getContent());
        return null;
    }

    /**
     * 缩小或放大图片
     * @param data 图片的byte数据
     * @param w 需要缩到的宽度
     * @param h 需要缩到高度
     * @return 缩放后的图片的byte数据
     */
    private byte[] ChangeImgSize(byte[] data)
    {
        int nw = this.imgWidth;
        int nh = this.imgHeight;
        byte[] newdata = null;
        try
        {
            BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));
            int w = bis.getWidth();
            int h = bis.getHeight();
            double sx = (double) nw / w;
            double sy = (double) nh / h;
            AffineTransform transform = new AffineTransform();
            transform.setToScale(sx, sy);
            AffineTransformOp ato = new AffineTransformOp(transform, null);
            // 原始颜色
            BufferedImage bid = new BufferedImage(nw, nh,
                    BufferedImage.TYPE_3BYTE_BGR);
            ato.filter(bis, bid);
            // 转换成byte字节
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bid, "jpeg", baos);
            newdata = baos.toByteArray();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return newdata;
    }

    /**
     * 将图片的以字节形式写到InputStream里
     */
    public ByteArrayInputStream createInputStream() throws Exception
    {
        findById();
        byte[] outResult = ChangeImgSize(annex.getContent());
        ByteArrayInputStream input = new ByteArrayInputStream(outResult);
        return input;
    }

    /**
     * 图片展示
     * @return
     * @throws Exception
     */
    public String showImg() throws Exception
    {
        setInputStream(createInputStream());
        return SUCCESS;
    }

    /**
     * 输出文件内容
     * @param os
     * @param content
     */
    private void write(OutputStream os, byte[] content)
    {
        try
        {
            os.write(content);
            os.flush();
        }
        catch (IOException ex)
        {
            throw new RuntimeException(ex);
        }
    }
    
    public String expAttach(){
        try
        {
            Attach attach;
            PageControl p= attachService.findAllByPage(0,0);
            List attachs =p.getResults();
            System.out.println("attachs.size():"+attachs.size());
            for(int i=0;i<attachs.size();i++){
                attach=(Attach)attachService.findById(new Integer(""+attachs.get(i)));
                outFile(attach);
            }
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return SUCCESS;
    }
    
    public void outFile(Attach attach){
        int i = 0;
        String doc="e:/doc/";
        try
        {
            if (attach != null&&attach.getContent()!=null)
            {
                File file = new File(doc+attach.getFullName());
                while (file.exists())
                {
                    file = new File(doc+ i + attach.getFullName());
                    i++;
                }
                java.io.FileOutputStream out = new java.io.FileOutputStream(file);
                out.write(attach.getContent());
                out.flush();
                out.close();
            }
        }
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            System.out.println(e.getMessage()+":"+attach.getId());
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            System.out.println(e.getMessage()+":"+attach.getId());
        }
    }

    /**
     * 获取文件POJO
     * @return
     */
    public A getAnnex()
    {
        return annex;
    }

    /**
     * 设置文件POJO
     * @param annex
     */
    public void setAnnex(A annex)
    {
        this.annex = annex;
    }

    /**
     * @return the uploadFile
     */
    public File getUploadFile()
    {
        return uploadFile;
    }

    /**
     * @param uploadFile the uploadFile to set
     */
    public void setUploadFile(File uploadFile)
    {
        this.uploadFile = uploadFile;
    }

    /**
     * @return the uFile
     */
    public File getUFile()
    {
        return uFile;
    }

    /**
     * @param file the uFile to set
     */
    public void setUFile(File file)
    {
        uFile = file;
    }

    public ByteArrayInputStream getInputStream()
    {
        return inputStream;
    }

    public void setInputStream(ByteArrayInputStream inputStream)
    {
        this.inputStream = inputStream;
    }

    public void setUploadFileContentType(String contentType)
    {
        this.contentType = contentType;
    }

    public void setUploadFileFileName(String fileName)
    {
        this.fileName = fileName;
    }

    /**
     * @return the imgWidth
     */
    public int getImgWidth()
    {
        return imgWidth;
    }

    /**
     * @param imgWidth the imgWidth to set
     */
    public void setImgWidth(int imgWidth)
    {
        this.imgWidth = imgWidth;
    }

    /**
     * @return the imgHeight
     */
    public int getImgHeight()
    {
        return imgHeight;
    }

    /**
     * @param imgHeight the imgHeight to set
     */
    public void setImgHeight(int imgHeight)
    {
        this.imgHeight = imgHeight;
    }

    public DictService getDictService()
    {
        return dictService;
    }

    public void setDictService(DictService dictService)
    {
        this.dictService = dictService;
    }

    public DictTypeService getDictTypeService()
    {
        return dictTypeService;
    }

    public void setDictTypeService(DictTypeService dictTypeService)
    {
        this.dictTypeService = dictTypeService;
    }

    public List<Dict> getLRefType()
    {
        return lRefType;
    }

    public void setLRefType(List<Dict> refType)
    {
        lRefType = refType;
    }

    public List<Dict> getLSecretType()
    {
        return lSecretType;
    }

    public void setLSecretType(List<Dict> secretType)
    {
        lSecretType = secretType;
    }

    public String getRefType()
    {
        return refType;
    }

    public void setRefType(String refType)
    {
        this.refType = refType;
    }

    public AnnexService getAnnexService()
    {
        return annexService;
    }

    public void setAnnexService(AnnexService annexService)
    {
        this.annexService = annexService;
    }

    public List<Annex> getAnnexList()
    {
        return annexList;
    }

    public void setAnnexList(List<Annex> annexList)
    {
        this.annexList = annexList;
    }

    public ShareReference getShareReference()
    {
        return shareReference;
    }

    public void setShareReference(ShareReference shareReference)
    {
        this.shareReference = shareReference;
    }

    public ShareReferenceService getShareReferenceService()
    {
        return shareReferenceService;
    }

    public void setShareReferenceService(
            ShareReferenceService shareReferenceService)
    {
        this.shareReferenceService = shareReferenceService;
    }

    public AttachService getAttachService()
    {
        return attachService;
    }

    public void setAttachService(AttachService attachService)
    {
        this.attachService = attachService;
    }

    public ProductReference getProductReference()
    {
        return productReference;
    }

    public void setProductReference(ProductReference productReference)
    {
        this.productReference = productReference;
    }

    public ProductReferenceService getProductReferenceService()
    {
        return productReferenceService;
    }

    public void setProductReferenceService(
            ProductReferenceService productReferenceService)
    {
        this.productReferenceService = productReferenceService;
    }
    
    public String getContent()
    {
        return content;
    }

    public void setContent(String content)
    {
        this.content = content;
    }

}
